package cn.agiledata.bank.linkbank.action;

import java.math.BigDecimal;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.ForeDict;
import cn.agiledata.bank.common.util.WebUtil;
import cn.agiledata.bank.hibernateBean.Bank;
import cn.agiledata.bank.hibernateBean.Transaction;
import cn.agiledata.bank.linkbank.exception.LinkBankException;
import cn.agiledata.bank.linkbank.form.WebPayRequestForm;
import cn.agiledata.bank.linkbank.impl.chinapay.ChinapayActionInfo;
import cn.agiledata.bank.linkbank.impl.cmb.CmbTelPayRequestFeekback;
import cn.agiledata.bank.linkbank.logic.payment.BankPayRequest;
import cn.agiledata.bank.linkbank.logic.payment.BankTelPayRequest;
import cn.agiledata.bank.linkbank.logic.payment.BankTelPayRequestFeekback;
import cn.agiledata.bank.linkbank.logic.payment.UnsPayRequest;
import cn.agiledata.bank.linkbank.service.BankNetPayService;
import cn.agiledata.bank.linkbank.service.BankTelPayService;
import cn.agiledata.bank.linkbank.service.WebPayService;
import com.vnv.infrastructure.action.IPBBaseAction;
import com.vnv.infrastructure.exception.IPBException;
import com.vnv.infrastructure.logic.IPBAppFactory;

public class BankPayRequestAction extends IPBBaseAction {
    private WebPayService webPayService;

    private BankNetPayService bankB2cNetPayService;

    private BankNetPayService bankB2bNetPayService;
    
    private BankNetPayService bankIntlNetPayService;

    private BankTelPayService bankTelPayService;

    private WebPayService getWebPayService() {
        if (this.webPayService == null) {
            this.webPayService = (WebPayService) IPBAppFactory
                    .getObj(ForeDict.SERVICE_WEB_PAY);
        }
        return this.webPayService;
    }

    private BankNetPayService getBankB2cNetPayService() {
        if (this.bankB2cNetPayService == null) {
            this.bankB2cNetPayService = (BankNetPayService) IPBAppFactory
                    .getObj(ForeDict.SERVICE_BANK_B2C_NET_PAY);
        }
        return this.bankB2cNetPayService;
    }

    private BankNetPayService getBankB2bNetPayService() {
        if (this.bankB2bNetPayService == null) {
            this.bankB2bNetPayService = (BankNetPayService) IPBAppFactory
                    .getObj(ForeDict.SERVICE_BANK_B2B_NET_PAY);
        }
        return this.bankB2bNetPayService;
    }
    
    private BankNetPayService getBankIntlNetPayService() {
        if (this.bankIntlNetPayService == null) {
            this.bankIntlNetPayService = (BankNetPayService) IPBAppFactory
                    .getObj(ForeDict.SERVICE_BANK_INTL_NET_PAY);
        }
        return this.bankIntlNetPayService;
    }

    private BankTelPayService getBankTelPayService() {
        if (this.bankTelPayService == null) {
            this.bankTelPayService = (BankTelPayService) IPBAppFactory
                    .getObj(ForeDict.SERVICE_BANK_TEL_PAY);
        }
        return this.bankTelPayService;
    }

    public int hasAccessPermission(int accessLevel, HttpServletRequest request)
            throws IPBException {
        return 1;
    }

    public ActionForward selectNetBank(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        request.setAttribute("BankList", getWebPayService()
                .getSupportedNetBanks());
        return mapping.findForward(FORWARD_SUCCESS);
    }

    public ActionForward bankPayRequest(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        WebPayService webPayService = (WebPayService) IPBAppFactory
                .getObj(ForeDict.SERVICE_WEB_PAY);
        WebPayRequestForm form = (WebPayRequestForm) actionForm;
        
        // 通过商户直连银行方式调用，取得实际银行编号
        if(request.getAttribute("bankCode") != null) {
        	form.setBankCode((String)request.getAttribute("bankCode"));
        }
        HttpSession session = request.getSession();
        UnsPayRequest unsPayRequest = webPayService.getUnsPayRequest(form,
				(UnsPayRequest) session.getAttribute(WebPayRequestAction.UNS_PAY_REQUEST));
        if (unsPayRequest == null) {
            throw LinkBankException.LOSE_REQUEST_DATA;
        }
        unsPayRequest.setAffirmable(true); // 默认为需要确认的

        // 设置操作类型
        String actionType = request.getParameter("actionType");
        if (actionType == null) {
            actionType = (String) request.getAttribute("actionType");
        }
        webPayService.setActionType(unsPayRequest, actionType);

        String transId = form.getTransId();
        if(transId == null) {
        	// 判断是否为直连跳转
        	transId = (String)request.getAttribute("transId");
        }
        // 此处若交易编号不为空，会使得新的交易数据覆盖原有的交易数据
        Transaction tran = webPayService
                .saveTransaction(transId, unsPayRequest);
        transId = tran.getTransId();
        //TODO zln 修正 2008-05-15 由于某些银行及卡接收不为空的remark会出现错误，此处保存在交易中后清空remark
        unsPayRequest.setRemark("");
        String webRootUrl = WebUtil.getRoot(request);
        BankPayRequest bankPayRequest = null;
        if(!webPayService.validateFee(unsPayRequest.getAmount(), unsPayRequest.getCreditAccount(), unsPayRequest.getActionType().getId().toString())) {
        	throw LinkBankException.FEE_EXCEED_AMOUNT;
        }
        if (webPayService.isBankNetPayMode(unsPayRequest)) {
            if (unsPayRequest.getBank() == null) {
                throw LinkBankException.UNSUPPORTED_NET_BANK;
            }
            BankNetPayService bankNetPayService = getBankB2cNetPayService();
            if (Constant.ACTION_TYPE_B2B_NET_PAY.equals(actionType)
                    || Constant.ACTION_TYPE_B2B_NET_INPOUR.equals(actionType)) {
                bankNetPayService = getBankB2bNetPayService();
            } else if (Constant.ACTION_TYPE_INTL_NET_PAY.equals(actionType)) {
            	// 外卡支付
            	bankNetPayService = getBankIntlNetPayService();
            }
            bankPayRequest = bankNetPayService.getBankNetPayRequest(
                    unsPayRequest, transId, webRootUrl);
            ChinapayActionInfo actionInfo=new ChinapayActionInfo();
            actionInfo.setAMOUNT(unsPayRequest.getAmount().multiply(new BigDecimal(100)).setScale(0).toString());
            actionInfo.setORDER_ID(transId);
//            String qdOrerderId=ChinapayActionInfo.jsonRequest("http://remotepaytest.qdone.net.cn/mpi/payServlet", actionInfo);
//            bankPayRequest.setBankUrl(bankPayRequest.getBankUrl()+"?PAY_ORDER_ID="+qdOrerderId+"&frontUrl="+request.getScheme() + "://"
//        			+ request.getServerName() + ":" + request.getServerPort()
//        			+ request.getContextPath()+"/chinapayCpNetPayResponse.do");
            /*bankPayRequest.setBankUrl(bankPayRequest.getBankUrl()+"?frontUrl="+request.getScheme() + "://"
        			+ request.getServerName() + ":" + request.getServerPort()
        			+ request.getContextPath()+"/chinapayCpNetPayResponse.do");*/
            bankPayRequest.setBankUrl(bankPayRequest.getBankUrl()+"?frontUrl=" + Constant.WEBROOT_URL
        			+ request.getContextPath()+"/chinapayCpNetPayResponse.do");
        } else if (webPayService.isBankTelPayMode(unsPayRequest)) {
            if (unsPayRequest.getBank() == null) {
                throw LinkBankException.UNSUPPORTED_TEL_BANK;
            }
            String orderTelephone = request.getParameter("orderTelephone");
            BankTelPayService bankTelPayService = getBankTelPayService();
            bankTelPayService.validateOrderTelephone(orderTelephone);
            bankPayRequest = bankTelPayService.getBankTelPayRequest(
                    unsPayRequest, transId, orderTelephone, webRootUrl);
            Bank bank = unsPayRequest.getBank();
            BankTelPayRequestFeekback requestFeekback = bankTelPayService
                    .sendBankTelPayRequest(bank.getBankCode(),
                            (BankTelPayRequest) bankPayRequest);
            // zln 修正 20080414 修正未读取银行电话银行号码的问题
            CmbTelPayRequestFeekback  cbmTfb = (CmbTelPayRequestFeekback)requestFeekback;
            cbmTfb.setTelBankNo(bank.getTelBankNo());
            request.setAttribute("bankPayRequestFeekback", cbmTfb);
            request.setAttribute("bank", bank);
        }
        request.setAttribute("bankPayRequest", bankPayRequest);
        request.getSession().removeAttribute("WebPayRequestForm");

        return mapping.findForward(FORWARD_SUCCESS);
    }

    public ActionForward selectTelBank(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        request.setAttribute("BankList", getBankTelPayService()
                .getSupportedBanks());
        return mapping.findForward(FORWARD_SUCCESS);
    }

}
